//
//  ReadMe.swift
//  项目部署
//
//  Created by apple on 16/8/7.
//  Copyright © 2016年 itcast. All rights reserved.
//

import Foundation


/*

    - 为什么使用readMe文件
        - 时间久远 你可能忘记了 如果一年半载你在需要在该项目添加功能或者修改功能  通过readMe文件可以教你快速回忆起项目
        - 如果你做的外包项目 
            - 哪些类是什么意思  一些主要功能点提示
        - 如果你在你上班的时候偷偷的面试去了 然后 你现在是15k 找到一个25k 着急飞
            - 项目交接 

        - 我 我会把一些主要的业务逻辑写在里面 知识点回顾 定义写在里面 便于你们课下复习
 
 ====================================================================
 - 第十二天
 - 读取bundle文件 中 default 和 emoji  和 lxh 文件夹下面的info.plist文件 (一维数组)
 - defaut  108  显示6页   20,20,20,20,20,8
 - emoji   80   显示4页   20,20,20,20
 - lxh     40   显示2页   20,20
 
 
 - 如何生成一个二维数组
 - default  108  显示6页   20,20,20,20,20,8
 [[0,19],[20,39],[40,59]...[100,107]]
 - emoji  80  显示4页   20,20,20,20
 [[0,19],[20,39],[40,59]...[60,79]]
 - lxh  40  显示2页   20,20
 [[0,19],[20,39]]
 
 
 ====================================================================
 - 第十天
 - 右侧按钮是否可以点击
 - 设置代理 (textView)
 - 自定义textView 里面添加占位label (左侧=5  顶部 = 8)
 - override var font:Font
 - 通过didSet 监听  改变占位文字的字体
 - 占位文字抛出 可以在外界设置
 - 代理已经在控制器中使用了 所以控件中不能使用了 所以使用监听系统通知
 - 自定义BottomView
 - 自定义pictureView (0||9 只显示图片) 其他最后一个显示为加号图片
 - 学习uiiimagepikercontroller
 - 得到图片给pictureView 在pictureView提供一个方法 供外界调用
 - 添加到数组中 最重要 一定要记得刷新UI
 - 监听系统键盘通知 frame 将要改变  endframe  得到他的y轴 更改约束
 
 
 ====================================================================
 - 第九天
 - 时间格式化
 - 如果微博时间和当前时间比较
 -如果是今年
 - 如果是今天
 - 如果小于60秒  显示 刚刚
 - 如果大于等于60 && 小于3600  显示 xx分钟前
 - 其他   显示  xx小时前
 - 如果是昨天
 -  2016年08月14日 20:20:20  显示   昨天 20:20
 - 其他
 -  2016年06月14日 20:20:20  显示    06月14日 20:20
 - 如果不是今年
 -  2014年06月14日 20:20:20  显示 2014年06月14日 20:20
 
 
 ====================================================================
 - 第八天
 
 - 第八天内容回顾
 - HMStatusModel 中添加一个属性 retweet_status (需要我们自己做字典转模型的操作)
 - 卸载bottomView.top约束
 - 如果有转发微博retweet_status != nil
 - 赋值
 - bottomView.top == retweetView.bottom
 - 显示转发微博
 - 反之 retweet_status == nil
 - bottomView.top == originalview.bottom
 - 隐藏转发微博
 
 - 自定义配图
 - 原创微博
 - 添加字段 pic_urls 其实一个数组 (创建模型 pictureInfo)
 - 写在原创微博.bottom 约束
 - 如果pic_urls.count > 0  代表有配图
 - 赋值
 - 原创微博.bottom == 配图的.bottom
 - 显示配图
 - 反之 代表没有配图
 - 原创微博.bottom == 微博正文的.bottom
 - 隐藏配图
 
 - 转发微博
 - 添加字段 pic_urls 其实一个数组 (创建模型 pictureInfo)
 - 写在转发微博.bottom 约束
 - 如果pic_urls.count > 0  代表有配图
 - 赋值
 - 转发微博.bottom == 配图的.bottom
 - 显示配图
 - 反之 代表没有配图
 - 转发微博.bottom == 微博正文的.bottom
 - 隐藏配图
 
 
 - 是否是gif图片 通过判断url的后缀是否是 .gif (隐藏和显示)
 - 处理微博来源
 - 首先判断 是否包含一个特殊字符
 - 获取 开始和介绍位置字符的range
 - 通过range 或者index
 - 通过String subStringrange 方法 完成字符串的截取
 
 - 处理底部视图 转发评论赞 业务逻辑
 
 - 如果 count <= 0  直接显示 转发 评论 赞
 - 如果 count > 0 && count < 10000  是多少显示多少  示例  8888  8888
 - 如果 count >= 10000   示例 12000   显示  1.2万
 - 如果 count%10000 == 0   示例 20000  显示  2万
 -------------------------------------------------------------------------------------------
 
 
 
 - 第七天业务逻辑分析
 
 - 底部视图的转发 评论 赞  业务逻辑
 - 如果 count <= 0  直接显示 转发 评论 赞
 - 如果 count > 0 && count < 10000  是多少显示多少  示例  8888  8888
 - 如果 count >= 10000   示例 12000   显示  1.2万
 - 如果 count%10000 == 0   示例 20000  显示  2万
 - 转发微博逻辑分析
 - 卸载底部视图的约束
 - 如果retweeted_status == nil  没有转发微博
 - 底部视图的top == 原创微博的bottom
 - 隐藏转发微博(cell复用问题)
 
 - 反之 有转发微博
 - 赋值
 - 底部视图的top == 转发微博的bottom
 - 显示转发微博(cell复用问题)
 
 
 - 由于我们使用的是tableView  那么cell 是复用的 如果滚动tableView 离开屏幕后 cell 到缓存池中 将要显示的cell 从缓存池中那 如果缓存池中没有 直接创建(创建的话 cell 原创转发底部)
 - 但是可能你根本就灭有转发微博 所以需要隐藏
 - 如果下一条显示有转发微博 但是从缓存池中拿出来的cell 的转发微博是隐藏的 那么我们根本看不到 所以要显示转发微博
 
 
 - 关于约束问题
 - 如果被约束的对象 相对于的对象没有发生改变 可以使用update
 - 如果被约束的对象 相对于的对象发生了改变 使用update 无效 需要先卸载 然后在约束 如果约束的时候 使用update 和make 均可
 

 
 ====================================================================
 - 第七天
 
 - 首页开发
 - 请求数据 -> Vc -> 抽取NetworkTools -> 抽取ViewModel中
 - ViewModel 中请求数据和提供数据
 - 分析首页cell
 - 原创
 - 转发
 - 底部视图
 - StatusViewModel 叫他管理model  给cell提供数据
 - 也就是说需要StatusViewModel 有一个属性 为model
 - 在StatusViewModel实例化 走构造函数的时候 必须给model 赋值 (通过重载构造函数)
 - 在对StatusViewModel实例化的时候 还要给会员等级和会员认证 计算显示本地的image
 - 当StatusViewModel 实例化ok以后 其身上的属性 均有值  而且不会再改变了
 - 目前其身上的属性 为存储型属性
 
====================================================================
    - 第六天
        - 上午知识点回顾
            - 通过token 和 uid 获取个人信息数据
                - 把头像和名字的字段保存起来 使用一个模型(userAccountModel)
            - 以上使用的是 AFN 直接请求网络数据
            - 拖入封装好的AFN网络工具类 使用公共方法请求数据
            - 把HMNetworkTools 帮我们创建两个方法 请求 userAccount 和请求userInfo
            - 外界直接使用HMNetworkTools 里面的两个方法请求数据
                - 成功的回调
                - 失败的回调
            - 因为我们使用的MVVM模式开发项目 所以我们要把网络请求的事情交给ViewModel
            - 创建了ViewModel 把请求的事情copy到 ViewModel 而控制器只需要知道成功或者失败(通过闭包告知控制器)
            - 通过归档和解档保存对象
                - 在模型中 NSCoding 
                    - encode
                    - initCode
                - 控制器委托ViewModel 保存对象 和获取对象的方法
                    - saveUserAccount
                    - getUserAccount
            - 为了不重复操作沙盒 所以在当前ViewModel 添加一个属性为userAccount
            - 当外界使用当前ViewModel 这个单例的时候 也就会走哦init方法 我要对userAccount 赋值 也就是从沙盒中获取对象
                - 为了解决第一次使用单例的时候 userAccount 为nil 
                    - 必须在\保存对象的时候 给单例中的属性赋值
            - 在ViewModel 创建一个属性 accessToken 
                - 如果userAccount.accessToken == nil 返回accessToken== nil
                - 反之 如果过期了返回accessToken== nil
                    - 如果没有过期  返回accessToken== userAccount.accessToken
            - 在ViewModel中 创建一个属性 为isLogin
                    - 如果accessToken== nil 代表没有登录
                    - 反之 代表登录了

            - 创建欢迎界面 
                    - 背景图片
                    - 头像
                    - 欢迎回来
                        - 当界面已经显示后 给头像设置阻尼动画
                            - 需要更改约束 update  self.view.layoutIfNeet 强制刷新UI


            - 如果判断根控制器的选择
                - 如果用户登录了  - rootVc = WelComeVc
                - 如果用户没有登录 - rootVc = MainVc(显示的访客视图)
            - 通知的使用
                - 如果用户没有登录
                    -MainVc(显示的访客视图) -> OAuth界面 -> 成功 -> 关闭 OAuth界面 -> 发送通知告知appdelete切换根控制器为 -> WelComeVc -> 动画完成后 -> MainVc(但是显示的不是访客视图 而是登录状态)
                
                - 如果用户登录了
                    - WelComeVc -> 动画完成后 -> MainVc(但是显示的不是访客视图 而是登录状态)








        - 发送通知切换根控制器业务逻辑
            - 如果在第一次登陆 到OAuthVc中 如果保存数据成功 告知appdelegate 切换根控制器为WelComeVc
            - 如果在WelComeVc 动画完成后 告知appdelegate 切换根控制器为 HMMainVc


        - 如果用户没有登陆    window.RootVc == HMMainVc
        - 如果用户已经登陆了   window.RootVc == WelComeVc

====================================================================
    - 第五天
        - 内容预告
            - VisitorView 中的按钮点击事件抛到控制器中
            - 学习单例
            - AFN网络封装
            - OAuth授权介绍
            - 微博开发者平台注册应用
            - 搭建OAuth界面
            - JS注入
            - 监听webView代理方法 截取授权码
            - 通过授权码获取accessToken
            - 通过accessToken 获取个人信息数据
            - ViewModel 抽取
            - 保存用户信息数据 使用归档和解档

        - 知识点讲解
            - OAuth授权
                - open auth  开发的授权

            - 登录&注册界面  
                - 用户名和密码  正确的话   登录成功
                    - 服务器会返回来  或者userId
                    - 当你在请求数据的时候 可能需要userId (人的身份证)
                    - 关注医生  取消关注医生
                        - 我的id = 100
                        - 医生的id == 200
                    - 如果我想获取我关注医生的列表

            - OAuth授权流程介绍
                - 登录微博开发者平台 www.open.weibo.com
                - 注册账号 成功开发者(个人开发者, 公司开发者)
                - 注册应用 
                    - appKey
                    - appSecret
                - 设置回调页
                - 添加测试账号
                - 加载webView页面



====================================================================
    - 第四天 回顾
        - 项目部署到开源中国的码云
        - 按照码云的提示 生成公钥和私钥
        - 把公钥配置的码云中
        - 创建一个共有项目
        - git clone 当前项目克隆到本地
        - 添加忽略文件 一定要先添加
        - 创建项目 和项目相关设置
        - 确定项目文件夹
            - Model
            - View
                - Main
                - Home
                - Message
                - Discover
                - Profile
            - ViewModel 
            - Libs
            - Common
        - 添加子控制器
            - 抽取出一个添加子控制器的公共方法
            - 自定义tabBar (通过kvc 给系统的只读属性赋值)
            - 添加撰写按钮和遍历tabBar子控件设置frame
        - 抽取基类(HMVisitorVc)
        - 自定义VisitorView
            - 设置圆圈动画
            - 提供一个方法供外界调用 在不同的控制器中显示不同的icon和信息
            - 使用可选值 为nil 默认认为是首页 因为首页还要设置圆圈动画
        - Swift中 代理和协议的使用


====================================================================
    - 第三天
        - 项目部署
            - 开源中国  git
            - 两种协议 
                    - HTTPS
                    - SSH


            - RSA秘钥对 - 它是一个非对称加密(加密效率极低)
                - 私钥 对项目加密
                - 公钥 对项目解密
            - 为什么对项目加密
                - 防止项目泄露


            - 加密过程
                - 创建一个私钥
                - 生成一个公钥 
                - 把公钥给服务器
                - 随机生成一个AES秘钥
                - 把AES 通过私钥加密后 通过网络给服务器
                - 通过AES给项目加密
                - 把加密后的项目给服务器
                - 服务器通过公钥把加密后的AES 解密
                - 服务器通过解密后的AES 把项目解密




ssh-keygen -t rsa -C "smile_faner@163.com"


































































































*/